/* eslint-disable */
import qs from 'qs';
import axios from 'axios';
import { JSONParse } from 'utils';
import { APIError, RequestError } from 'utils/error';
import createURL from './createURL';

const isDev = process.env.NODE_ENV === 'development';

const codeMessage = {
  0: '请求服务器异常',
  200: '服务器成功返回请求的数据。',
  201: '新建或修改数据成功。',
  202: '一个请求已经进入后台排队（异步任务）。',
  204: '删除数据成功。',
  400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
  401: '用户没有权限（令牌、用户名、密码错误）。',
  403: '用户得到授权，但是访问是被禁止的。',
  404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
  406: '请求的格式不可得。',
  408: '请求超时，请稍后重试',
  410: '请求的资源被永久删除，且不会再得到的。',
  422: '当创建一个对象时，发生一个验证错误。',
  500: '服务器发生错误，请检查服务器。',
  502: '网关错误。',
  503: '服务不可用，服务器暂时过载或维护。',
  504: '网关超时。',
};

const fetch = axios.create({
  baseURL: isDev ? '' : createURL('h5'),
  retry: 3,
  retryDelay: 1000,
  crossDomain: true,
  withCredentials: true,
  timeout: 15000,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
  },
});

// Fixing Axios.create() has no all & spread & Cancel & CancelToken & isCancel function
fetch.Cancel = axios.Cancel;
fetch.CancelToken = axios.CancelToken;
fetch.isCancel = axios.isCancel;
fetch.all = axios.all;
fetch.spread = axios.spread;
fetch.get = (...options) => {
  const [url, params, config] = options;
  return fetch({
    method: 'get',
    url,
    params,
    ...config,
  });
};

fetch.interceptors.request.use((config) => {
  const options = { ...config };

  options.url = createURL(options.url);

  // injection sessionid
  if (/POST|PUT/i.test(options.method) && !(options.data instanceof FormData)) {
    options.data = qs.stringify(config.data);
  }

  return options;
});

fetch.interceptors.response.use(
  (response) => {
    const { config = {}, data = {}, request } = response;
    const code = data.code - 0;
    const { url } = config;
    const options = {
      ...data,
      code,
    };

    // 返回默认值
    if (options.data === null || options.data === undefined) {
      options.data = {};
    }

    // 处理 API 异常
    // if (code !== 0) {
    //   const error = new APIError(options.message);
    //   error.code = code;
    //   error.url = url;
    //   error.body = request.responseText;

    //   return Promise.reject(error);
    // }

    return options;
  },
  (response) => {
    const { config = {}, request, message } = response;
    let { status } = request;

    if (/timeout/.test(message)) {
      status = 408;
    }
    const { error: responseError, message: responseMessage } = JSONParse(request.responseText);
    const errorText = responseError || responseMessage || codeMessage[status] || message;

    const error = new RequestError(errorText);

    return Promise.reject();
  }
);

export default fetch;
